package yamaia.musicPlayerTester;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;

public class customTabWidget extends LinearLayout implements OnFocusChangeListener {

    private OnTabSelectionChanged mSelectionChangedListener;
    private Context mContext;

    private int mSelectedTab = 0;

    private Drawable mLeftStrip;
    private Drawable mRightStrip;

    private boolean mDrawBottomStrips = true;
    private boolean mStripMoved;
    String TAG = "reavelvWidget";

    private Drawable mDividerDrawable;

    private final Rect mBounds = new Rect();

    public customTabWidget(Context context) {
        this(context, null);
    	mContext = context;
    }

    public customTabWidget(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.tabWidgetStyle);
    	Log.d(TAG, "customTabWidget1");
    	mContext = context;
    }

    public customTabWidget(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs);
    	mContext = context;
    	Log.d(TAG, "customTabWidget2");

        TypedArray a =
            context.obtainStyledAttributes(attrs, R.styleable.TabWidget,
                    defStyle, 0);

        mDrawBottomStrips = a.getBoolean(R.styleable.TabWidget_tabStripEnabled, true);
        mDividerDrawable = a.getDrawable(R.styleable.TabWidget_divider);
        mLeftStrip = a.getDrawable(R.styleable.TabWidget_tabStripLeft);
        mRightStrip = a.getDrawable(R.styleable.TabWidget_tabStripRight);

        a.recycle();

        initTabWidget();
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mStripMoved = true;
    	Log.d(TAG, "onSizeChanged");
        super.onSizeChanged(10, h, oldw, oldh);
    }

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        // Always draw the selected tab last, so that drop shadows are drawn
        // in the correct z-order.
    	Log.d(TAG, "getChildDrawingOrder");
        if (i == childCount - 1) {
            return mSelectedTab;
        } else if (i >= mSelectedTab) {
            return i + 1;
        } else {
            return i;
        }
    }    
    
    private void initTabWidget() {
        setOrientation(LinearLayout.HORIZONTAL);
    	Log.d(TAG, "initTabWidget");

        final Context context = mContext;
        final Resources resources = context.getResources();
        

        // Use modern color scheme for Eclair and beyond
        if (mLeftStrip == null) {
            mLeftStrip = resources.getDrawable(
                    R.drawable.tab_bottom_left);
        }
        if (mRightStrip == null) {
            mRightStrip = resources.getDrawable(
                    R.drawable.tab_bottom_right);
        }
    

        // Deal with focus, as we don't want the focus to go by default
        // to a tab other than the current tab
        setFocusable(true);
        setOnFocusChangeListener(this);
    }
	
	public View getChildTabViewAt(int index) {
        // If we are using dividers, then instead of tab views at 0, 1, 2, ...
        // we have tab views at 0, 2, 4, ...
    	Log.d(TAG, "getChildTabViewAt");
        if (mDividerDrawable != null) {
            index *= 2;
        }
        return getChildAt(index);
    }
	
	public int getTabCount() {
    	Log.d(TAG, "getTabCount");
        int children = getChildCount();

        // If we have dividers, then we will always have an odd number of
        // children: 1, 3, 5, ... and we want to convert that sequence to
        // this: 1, 2, 3, ...
        if (mDividerDrawable != null) {
            children = (children + 1) / 2;
        }
        return children;
    }
	
	public void setDividerDrawable(Drawable drawable) {
    	Log.d(TAG, "setDividerDrawable");
	       mDividerDrawable = drawable;
	       requestLayout();
	       invalidate();
	}
	 
	public void setDividerDrawable(int resId) {
    	Log.d(TAG, "setDividerDrawable");
	       mDividerDrawable = mContext.getResources().getDrawable(resId);
	       requestLayout();
	       invalidate();
	}
	
	public void setLeftStripDrawable(int resId) {
    	Log.d(TAG, "setLeftStripDrawable");
	       mLeftStrip = mContext.getResources().getDrawable(resId);
	       requestLayout();
	       invalidate();
	}
	
	public void setRightStripDrawable(Drawable drawable) {
    	Log.d(TAG, "setRightStripDrawable");
        mRightStrip = drawable;
        requestLayout();
        invalidate();    
    }
	
	public void setRightStripDrawable(int resId) {
    	Log.d(TAG, "setRightStripDrawable");
	       mRightStrip = mContext.getResources().getDrawable(resId);
	       requestLayout();
	       invalidate();
	}
	
	public void setStripEnabled(boolean stripEnabled) {
    	Log.d(TAG, "setStripEnabled");
        mDrawBottomStrips = stripEnabled;
        invalidate();
    }
	
	public boolean isStripEnabled() {
    	Log.d(TAG, "isStripEnabled");
        return mDrawBottomStrips;
    }
	
	@Override
    public void childDrawableStateChanged(View child) {
    	Log.d(TAG, "childDrawableStateChanged");
        if (getTabCount() > 0 && child == getChildTabViewAt(mSelectedTab)) {
            // To make sure that the bottom strip is redrawn
            invalidate();
        }
        super.childDrawableStateChanged(child);
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    	Log.d(TAG, "dispatchDraw");

        // Do nothing if there are no tabs.
        if (getTabCount() == 0) return;

        // If the user specified a custom view for the tab indicators, then
        // do not draw the bottom strips.
        if (!mDrawBottomStrips) {
            // Skip drawing the bottom strips.
            return;
        }

        final View selectedChild = getChildTabViewAt(mSelectedTab);

        final Drawable leftStrip = mLeftStrip;
        final Drawable rightStrip = mRightStrip;

        leftStrip.setState(selectedChild.getDrawableState());
        rightStrip.setState(selectedChild.getDrawableState());

        if (mStripMoved) {
            final Rect bounds = mBounds;
            bounds.left = selectedChild.getLeft();
            bounds.right = selectedChild.getRight();
            final int myHeight = getHeight();
            leftStrip.setBounds(Math.min(0, bounds.left - leftStrip.getIntrinsicWidth()),
                    myHeight - leftStrip.getIntrinsicHeight(), bounds.left, myHeight);
            rightStrip.setBounds(bounds.right, myHeight - rightStrip.getIntrinsicHeight(),
                    Math.max(getWidth(), bounds.right + rightStrip.getIntrinsicWidth()), myHeight);
            mStripMoved = false;
        }

        leftStrip.draw(canvas);
        rightStrip.draw(canvas);
    }
    
    public void setCurrentTab(int index) {
    	Log.d(TAG, "setCurrentTab");
        if (index < 0 || index >= getTabCount()) {
            return;
        }

        getChildTabViewAt(mSelectedTab).setSelected(false);
        mSelectedTab = index;
        getChildTabViewAt(mSelectedTab).setSelected(true);
        mStripMoved = true;
    }
    
    public void focusCurrentTab(int index) {
    	Log.d(TAG, "focusCurrentTab");
        final int oldTab = mSelectedTab;

        // set the tab
        setCurrentTab(index);

        // change the focus if applicable.
        if (oldTab != index) {
            getChildTabViewAt(index).requestFocus();
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
    	Log.d(TAG, "setEnabled");
        int count = getTabCount();

        for (int i = 0; i < count; i++) {
            View child = getChildTabViewAt(i);
            child.setEnabled(enabled);
        }
    }
    
    @Override
    public void addView(View child) {
    	Log.d(TAG, "addView");
        if (child.getLayoutParams() == null) {
            final LinearLayout.LayoutParams lp = new LayoutParams(
                    0,
                    ViewGroup.LayoutParams.MATCH_PARENT, 1.0f);
            lp.setMargins(0, 0, 0, 0);
            child.setLayoutParams(lp);
        }

        // Ensure you can navigate to the tab with the keyboard, and you can touch it
        child.setFocusable(true);
        child.setClickable(true);

        // If we have dividers between the tabs and we already have at least one
        // tab, then add a divider before adding the next tab.
        if (mDividerDrawable != null && getTabCount() > 0) {
            ImageView divider = new ImageView(mContext);
            final LinearLayout.LayoutParams lp = new LayoutParams(
                    mDividerDrawable.getIntrinsicWidth(),
                    LayoutParams.MATCH_PARENT);
            lp.setMargins(0, 0, 0, 0);
            divider.setLayoutParams(lp);
            divider.setBackgroundDrawable(mDividerDrawable);
            super.addView(divider);
        }
        super.addView(child);

        // TODO: detect this via geometry with a tabwidget listener rather
        // than potentially interfere with the view's listener
        child.setOnClickListener(new TabClickListener(getTabCount() - 1));
        child.setOnFocusChangeListener(this);
    }
    
    void setTabSelectionListener(OnTabSelectionChanged listener) {
    	Log.d(TAG, "setTabSelectionListener");
        mSelectionChangedListener = listener;
    }
    
	@Override
	public void onFocusChange(View v, boolean hasFocus) {
    	Log.d(TAG, "onFocusChange");
        if (v == this && hasFocus && getTabCount() > 0) {
            getChildTabViewAt(mSelectedTab).requestFocus();
            return;
        }

        if (hasFocus) {
            int i = 0;
            int numTabs = getTabCount();
            while (i < numTabs) {
                if (getChildTabViewAt(i) == v) {
                    setCurrentTab(i);
                    mSelectionChangedListener.onTabSelectionChanged(i, false);
                    break;
                }
                i++;
            }
        }
    }
    
    private class TabClickListener implements OnClickListener {

        private final int mTabIndex;

        private TabClickListener(int tabIndex) {
            mTabIndex = tabIndex;
        }

        public void onClick(View v) {
            mSelectionChangedListener.onTabSelectionChanged(mTabIndex, true);
        }
    }
	
	static interface OnTabSelectionChanged {
        /**
         * Informs the TabHost which tab was selected. It also indicates
         * if the tab was clicked/pressed or just focused into.
         *
         * @param tabIndex index of the tab that was selected
         * @param clicked whether the selection changed due to a touch/click
         * or due to focus entering the tab through navigation. Pass true
         * if it was due to a press/click and false otherwise.
         */
        void onTabSelectionChanged(int tabIndex, boolean clicked);
    }
	
	
}
